Skip to content

Persist changed-files expansion state per thread#1858

Merged
juliusmarminge merged 6 commits intopingdotgg:mainfrom
Marve10s:fix/thread-changed-files-expansion
Apr 10, 2026
Merged

Persist changed-files expansion state per thread#1858
juliusmarminge merged 6 commits intopingdotgg:mainfrom
Marve10s:fix/thread-changed-files-expansion

Conversation

@Marve10s
Copy link
Copy Markdown
Contributor

@Marve10s Marve10s commented Apr 9, 2026

What changed

  • Persist changed-files tree expansion state per thread instead of keeping it inside MessagesTimeline component state.
  • Move the expansion source of truth into uiStateStore, keyed by scoped thread id and turn id.
  • Clean up stored expansion overrides when threads disappear.

Why

The changed-files tree reset to expanded whenever the thread view unmounted and mounted again. That happened because the expansion map lived inside MessagesTimeline as local React state.

Notes

  • Default behavior stays the same: changed-files trees start expanded.
  • Only collapsed overrides are stored; expanding again removes the override.
  • I checked the current open PR set and did not find an open PR specifically implementing this thread-scoped changed-files persistence. A few open PRs touch MessagesTimeline.tsx, but for unrelated work.

Validation

  • bun fmt
  • bun lint
  • bun typecheck
  • bun run --cwd apps/web test --run src/uiStateStore.test.ts src/components/chat/MessagesTimeline.test.tsx

Note

Persist changed-files expansion state per thread turn in UI store

  • Adds threadChangedFilesExpandedById to uiStateStore.ts, tracking per-thread per-turn collapse state in localStorage. Only collapsed (false) states are stored to minimize persisted footprint.
  • Lifts expansion state out of internal MessagesTimeline component state into the parent ChatView, passing it down via new changedFilesExpandedByTurnId and onSetChangedFilesExpanded props.
  • Prunes stale expansion overrides when threads are pruned (syncThreads) or their UI state is cleared (clearThreadUi).
  • Behavioral Change: the 'Changed files' expansion state now persists across page reloads and is shared across components reading from the same thread key.

Macroscope summarized b3979fc.


Note

Low Risk
Low risk UI-state change: moves changed-files expand/collapse state from component-local state into the persisted uiStateStore, with pruning/sanitization to avoid unbounded localStorage growth.

Overview
Persists “Changed files” expand/collapse per thread/turn so the tree no longer resets when MessagesTimeline unmounts/remounts.

Adds threadChangedFilesExpandedById to uiStateStore (including localStorage hydrate/sanitize, persist, and pruning via syncThreads/clearThreadUi) and wires ChatView to read/write this state and pass it into MessagesTimeline, which is now controlled via new changedFilesExpandedByTurnId/onSetChangedFilesExpanded props. Tests were updated to cover the new store behavior and required props.

Reviewed by Cursor Bugbot for commit b3979fc. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 993228d0-3a1d-4610-b908-9f7442199ebf

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Apr 9, 2026
The `?? {}` fallback treated a missing key in `right` as an empty
object, so two records with different outer keys but empty inner
values were incorrectly considered equal. Check `key in right`
before comparing inner records.
@Marve10s Marve10s marked this pull request as ready for review April 9, 2026 20:00
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp bot commented Apr 9, 2026

Approvability

Verdict: Approved

Straightforward UI state persistence feature that remembers whether file change sections are expanded/collapsed per chat thread. The changes follow existing patterns in the codebase, are well-tested, and have no runtime behavior impact beyond local UI preferences stored in localStorage.

You can customize Macroscope's approvability policy. Learn more.

macroscopeapp[bot]
macroscopeapp bot previously approved these changes Apr 9, 2026
@macroscopeapp macroscopeapp bot dismissed their stale review April 10, 2026 16:11

Dismissing prior approval to re-evaluate b3979fc

@juliusmarminge juliusmarminge merged commit 9385314 into pingdotgg:main Apr 10, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants